﻿Imports System.Threading

Public Class QueryFilesWalker

    Public Event SearchCompleted(ByVal qname As String, ByVal isStale As Boolean)

    Private _rootPath As String
    
    Public Property RootPath() As String
        Get
            Return _rootPath
        End Get
        Set(ByVal value As String)
            If value.EndsWith("\") = False Then
                value = value & "\"
            End If
            _rootPath = value
        End Set
    End Property

    Public Sub walkFiles()

        Dim di As New IO.DirectoryInfo(Me.RootPath & "Queries")
        Dim files As IO.FileInfo() = di.GetFiles("*.qry")

        'list the names of all files in the specified directory
        For Each thisFile As IO.FileInfo In files
            Dim sf As StaleQueryFinder = New StaleQueryFinder
            sf.RootPath = Me.RootPath
            sf.QueryName = thisFile.Name.Replace(".qry", String.Empty)
            ThreadPool.QueueUserWorkItem(AddressOf FindTextCallback, sf)

        Next

    End Sub

    Public Sub FindTextCallback(ByVal x As Object)

        Dim sf As StaleQueryFinder = CType(x, StaleQueryFinder)
        sf.findText()
        RaiseEvent SearchCompleted(sf.QueryName, sf.IsStale)
    End Sub

End Class


Public Class StaleQueryFinder

    Public Event SearchCompleted(ByVal qname As String, ByVal isStale As Boolean)
    Private _rootPath As String
    Private _queryName As String
    Private _isStale As Boolean = False

    Public ReadOnly Property IsStale() As Boolean
        Get
            Return _isStale
        End Get
    End Property

    Public Property RootPath() As String
        Get
            Return _rootPath
        End Get
        Set(ByVal value As String)
            _rootPath = Value
        End Set
    End Property
    Public Property QueryName() As String
        Get
            Return _queryName
        End Get
        Set(ByVal value As String)
            _queryName = Value
        End Set
    End Property

    Public Sub findText()

        Dim subFolders As List(Of String) = New List(Of String)
        subFolders.Add("Pages")
        subFolders.Add("Forms")
        subFolders.Add("Macros")
        subFolders.Add("Modules")
        subFolders.Add("Queries")
        subFolders.Add("Reports")

        Dim searchString As String = Me._queryName.ToLower
        For Each subfl As String In subFolders
            Dim spath As String = Me._rootPath & subfl

            Dim staleQueryFileSearcher As New StaleQueryFileSearcher
            staleQueryFileSearcher.FilePath = spath
            staleQueryFileSearcher.SearchString = searchString
            If staleQueryFileSearcher.findText = True Then
                Me._isStale = False
                Return
            End If

        Next

        Me._isStale = True

    End Sub

End Class


Public Class StaleQueryFileSearcher
    ''' <summary>
    ''' String to find
    ''' </summary>
    Private _searchStr As String

    ''' <summary>
    ''' All files in this path are opened and searched for this string
    ''' </summary>
    Private _pathToSearchIn As String

    Public Property SearchString() As String
        Get
            Return _searchStr
        End Get
        Set(ByVal value As String)
            _searchStr = value
        End Set
    End Property

    Public Property FilePath() As String
        Get
            Return _pathToSearchIn
        End Get
        Set(ByVal value As String)
            _pathToSearchIn = value
        End Set
    End Property
    Public Function findText() As Boolean

        Dim searchString As String = Me.SearchString.ToLower
        'Debug.WriteLine("Thread for " & FilePath & " Starting for:" & Me.SearchString)
        Dim dirFiles As String() = IO.Directory.GetFiles(_pathToSearchIn, "*.*")
        For Each fileName As String In dirFiles
            'Console.WriteLine(fileName)
            Dim fileText As String = IO.File.ReadAllText(fileName)
            If fileText.ToLower.IndexOf(searchString) >= 0 Then
                Return True
            End If
        Next

        Return False

    End Function
End Class